using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Danser_AJAXEnabledWebApplication.User_Controls;
using Danser_Control.Exceptions;
using Danser_Entity.Entities;
using Danser_Entity.Queries.Data;
using Danser_Entity.Queries.Filters;

namespace Danser_AJAXEnabledWebApplication
{
    /// <summary>
    /// Page to handle users and permission roles for Danser system 
    /// </summary>
    public partial class Authorizations : AbstractPage
    {
        #region Constants:

        //Session keys IDs
        private const String SESSION_NEWROW = "NewRow";
        private const String SESSION_PERMISSION = "CurrentPermission";

        //objectDataSource parameter IDs
        private const String ODS_NEWROW = "newRow";
        private const String ODS_FILTER_PARAMETER = "filter";

        //column control IDs
        private const String ROW_SELECTOR_ID = "rowSelector";
        private const String ID_LABEL_ID = "IDLabel";
        private const String ID_TEXTBOX_ID = "IDTextBox";
        private const String NAME_TEXTBOX_ID = "nameTextBox";
        private const String PERMISSION_LABEL_ID = "permissionLabel";
        private const String PERMISSIONS_LIST_ID = "permissionDropDownList";

        //table names for filtering the Users DataGrid
        private readonly Groups[] SEARCH_TABLE_NAME =
            new Groups[] 
            {
                Groups.Users
            };

        #endregion

        #region Page Load:

        /// <summary>
        /// loads the page
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void Page_Load(object sender, EventArgs e)
        {
            base.Page_Load(sender, e);

            if (!IsPostBack) //first time
            {
                //feed columns list
                _pageFormatter.DisplayColumnsTemplate(dataGridView, columnsMultiSelectList, 1);
            }

            try
            {
                //to reset the parameter
                objectDataSource.SelectParameters[ODS_NEWROW].DefaultValue = "false";
            }
            catch (Exception exception)
            {
                HandleGenericErrorPage(exception);
            }
        }

        #endregion

        #region AbstractPage Implementation:

        /// <see cref="Danser_AJAXEnabledWebApplication.AbstractPage.InnerValidatePermission"/>
        protected override bool InnerValidatePermission(PermissionLevel permissionlevel)
        {
            return permissionlevel == PermissionLevel.Admin;
        }

        #endregion

        #region Filter Columns Pane:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void filterButton_Click(object sender, EventArgs e)
        {
            _pageFormatter.FilterColumnsByListSelection(dataGridView, columnsMultiSelectList);
        }

        #endregion

        #region Filter Rows Pane:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void filterUsersButton_Click(object sender, EventArgs e)
        {
            _pageFormatter.ToggleButtonText((Button)sender, new String[] {"Search Users", "Hide Search"});

            usersQueryPanel.Visible = !usersQueryPanel.Visible;

            usersQueryExpressionBuilder.setSearchingTables(SEARCH_TABLE_NAME);

            usersQueryExpressionBuilder.setBuilderMode(BuilderModes.BUILD_QUERY);
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void executeUserQueryButton_Click(object sender, EventArgs e)
        {
            //get the conditions generated by the expression builder
            IList<Condition> conditions = usersQueryExpressionBuilder.getConditions(true);

            if (conditions == null)
                return;

            //build a rule out of the conditions
            RuleExpression parsedRule = new RuleExpression(conditions);
            try
            {
                //when setting select parameter, SELECT method is automatically invoked
                objectDataSource.SelectParameters[ODS_FILTER_PARAMETER].DefaultValue =
                    parsedRule.ConditionsToString(true);
            }
            catch (Exception exception)
            {
                HandleGenericErrorPage(exception);
            }
        }

        #endregion

        #region Selecting Buttons:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void selectAllButton_Click(object sender, EventArgs e)
        {
            //can't select on edit mode
            if (dataGridView.EditIndex > -1)
                return;

            foreach (GridViewRow row in dataGridView.Rows)
            {
                CheckBox checkBox = row.FindControl(ROW_SELECTOR_ID) as CheckBox;
                checkBox.Checked = true;
            }
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void selectNoneButton_Click(object sender, EventArgs e)
        {
            //can't deselect on edit mode
            if (dataGridView.EditIndex > -1)
                return;

            foreach (GridViewRow row in dataGridView.Rows)
            {
                CheckBox checkBox = row.FindControl(ROW_SELECTOR_ID) as CheckBox;
                checkBox.Checked = false;
            }
        }

        #endregion

        #region Rows Handling Buttons:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void addButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView.EditIndex > -1)//another row is already in edit mode
                    return;

                //inserts an empty Item
                objectDataSource.Insert();

                //notify the SELECT method that there's a new row
                objectDataSource.SelectParameters[ODS_NEWROW].DefaultValue = "true";

                dataGridView.EditIndex = 0;
                Session[SESSION_NEWROW] = true;

                //set focus to first text box in row
                dataGridView.DataBind(); // update the rows count
                Page.SetFocus(((TextBox)dataGridView.Rows[dataGridView.EditIndex].FindControl(ID_TEXTBOX_ID)));
            }
            catch (Exception exception)
            {
                HandleGenericErrorPage(exception);
            }
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void modifyButton_Click(object sender, EventArgs e)
        {

            if (dataGridView.EditIndex > -1) //another row is already in edit mode
                return;

            objectDataSource.UpdateParameters["newRow"].DefaultValue = "false";
            try
            {
                //search for the first row seleced:
                for (int i = 0; i < dataGridView.Rows.Count; i++)
                {
                    CheckBox checkBox = dataGridView.Rows[i].FindControl(ROW_SELECTOR_ID) as CheckBox;
                    if (checkBox != null && checkBox.Checked)
                    {
                        //remember displayed permission
                        Label label = dataGridView.Rows[i].FindControl(PERMISSION_LABEL_ID) as Label;
                        Session[SESSION_PERMISSION] = label.Text;

                        dataGridView.EditIndex = i;
                        Session[SESSION_NEWROW] = false;

                        dataGridView.DataBind(); // to update grid's rows' mode
                        //do not let the user change the key
                        ((TextBox)dataGridView.Rows[dataGridView.EditIndex].FindControl(ID_TEXTBOX_ID)).Enabled = false;
                        //set focus to permissions drop down list - userID is now read only
                        Page.SetFocus(((DropDownList)dataGridView.Rows[dataGridView.EditIndex].FindControl(PERMISSIONS_LIST_ID)));
                        break;
                    }

                }
            }
            catch (Exception exception)
            {
                HandleGenericErrorPage(exception);
            }
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void removeButton_Click(object sender, EventArgs e)
        {
            if (dataGridView.EditIndex > -1) //another row is already in edit mode
                return;

            IList<int> rowsIndecies = new List<int>();
            //search for all the selected rows:
            for (int i = 0; i < dataGridView.Rows.Count; i++)
            {
                CheckBox checkBox = dataGridView.Rows[i].FindControl(ROW_SELECTOR_ID) as CheckBox;
                if (checkBox != null && checkBox.Checked)
                {
                    rowsIndecies.Add(i);
                }
            }

            try
            {
                foreach (int index in rowsIndecies)
                {
                    string userID = ((System.Web.UI.WebControls.Label)dataGridView.Rows[index].FindControl(ID_LABEL_ID)).Text;
                    objectDataSource.DeleteParameters[0/*="userId"*/].DefaultValue = userID;
                    dataGridView.DeleteRow(index);
                }
            }
            catch (Exception exception)
            {
                HandleGenericErrorPage(exception);
            }
        }

        #endregion

        #region Row Inner Buttons:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void saveRowButton_Click(object sender, EventArgs e)
        {
            if (dataGridView.EditIndex < 0)
                return;

            //empty string are not allowed to be saved
            if (((TextBox)dataGridView.Rows[dataGridView.EditIndex].FindControl(ID_TEXTBOX_ID)).Text.Equals(""))
                return;

            if (Convert.ToBoolean(Session[SESSION_NEWROW]))
            {
                objectDataSource.UpdateParameters["newRow"].DefaultValue = "true";
            }
            try
            {
                dataGridView.UpdateRow(dataGridView.EditIndex, false);
                
                objectDataSource.SelectParameters[ODS_NEWROW].DefaultValue = "false";
            }
            catch (DanserAuthorizationException exception)
            {
                HandleAuthorizationErrorPage(exception);
            }
            catch (Exception exception2)
            {
                HandleGenericErrorPage(exception2);
            }
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void cancelRowButton_Click(object sender, EventArgs e)
        {
            try
            {
                //delete the empty row added
                if (Convert.ToBoolean(Session[SESSION_NEWROW]))
                {
                    objectDataSource.DeleteParameters["newRow"].DefaultValue = "true";
                    dataGridView.DeleteRow(dataGridView.EditIndex);
                    return;
                }
                //else - the row is in edit mode
                if (dataGridView.EditIndex > -1)
                    dataGridView.EditIndex = -1;

                objectDataSource.SelectParameters[ODS_NEWROW].DefaultValue = "false";
            }
            catch (Exception exception)
            {
                HandleGenericErrorPage(exception);
            }
        }

        #endregion

        #region DataGrid Handlers:

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void dataGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            string id = ((TextBox)dataGridView.Rows[e.RowIndex].FindControl(ID_TEXTBOX_ID)).Text;
            string name = ((TextBox)dataGridView.Rows[e.RowIndex].FindControl(NAME_TEXTBOX_ID)).Text;
            string permission = ((DropDownList)dataGridView.Rows[e.RowIndex].FindControl(PERMISSIONS_LIST_ID)).SelectedValue;

            e.NewValues["userID"] = id;
            e.NewValues["name"] = name;
            e.NewValues["permission"] = permission;
        }

        /// <summary>
        /// event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void dataGridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex == dataGridView.EditIndex)
            {
                DropDownList permissions = e.Row.FindControl(PERMISSIONS_LIST_ID) as DropDownList;
                permissions.DataSource = Enum.GetNames(typeof(PermissionLevel));
                permissions.DataBind();

                permissions.SelectedValue = Session[SESSION_PERMISSION] as String;
            }
        }

        #endregion

    }
}
